﻿function Get-ConfigurationRepositoryManager
{
    [cmdletbinding(DefaultParameterSetName="none")]
    Param( 
        [Parameter(Mandatory=$true,ValueFromPipeline=$false)]
        [String]$LocalPath,

        [Parameter(Mandatory=$true,ValueFromPipeline=$false)]
        [String]$NetworkPath

    )
    Begin
    {
        $watch = [system.diagnostics.stopwatch]::StartNew()
        $eventId = Publish-ToMiddlewareLogs -Log (Get-LogMessage -Command $PSCmdlet.MyInvocation.MyCommand -Message "Start" -AdditionalData $PSBoundParameters)
    }
    End
    {
        $watch.Stop()
        $eventId = Publish-ToMiddlewareLogs -Log (Get-LogMessage -Command $PSCmdlet.MyInvocation.MyCommand -UniqueId $eventId -Message "End" -AdditionalData @{Duration=$watch.Elapsed})
    }
    Process
    {

        $ConfigurationRepositoryManager = new-Object PSObject -Property @{
                                                                          LocalPath=$LocalPath
                                                                          NetworkPath=$NetworkPath
                                                                          BaseConfigurationRootRelativePath = "BaseConfiguration"
                                                                         }
        
        
        $ConfigurationRepositoryManager | Add-Member -MemberType ScriptMethod -Name GetFullLocalPath -Value {
           .{
                param (	
                    [Parameter(Mandatory=$true)]
                    [ValidateNotNullOrEmpty()]
	                [String]$RelativePath
                )
                Process
                {
                    Join-Path -Path $this.LocalPath -ChildPath $RelativePath
                }
            } @args 
        } -Force

        $ConfigurationRepositoryManager | Add-Member -MemberType ScriptMethod -Name GetFullRemotePath -Value {
           .{
                param (	
                    [Parameter(Mandatory=$true)]
                    [ValidateNotNullOrEmpty()]
	                [String]$RelativePath
                )
                Process
                {
                    Join-Path -Path $this.NetworkPath -ChildPath $RelativePath
                }
            } @args 
        } -Force



        Write-Output $ConfigurationRepositoryManager
    }
}


function Get-BaseConfigurationDirectory
{
    [cmdletbinding(DefaultParameterSetName="none")]
    param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
        [PSObject]$CurrentObject
    )
    Begin
    {
        $watch = [system.diagnostics.stopwatch]::StartNew()
        $eventId = Publish-ToMiddlewareLogs -Log (Get-LogMessage -Command $PSCmdlet.MyInvocation.MyCommand -Message "Start" -AdditionalData $PSBoundParameters)
    }
    End
    {
        $watch.Stop()
        $eventId = Publish-ToMiddlewareLogs -Log (Get-LogMessage -Command $PSCmdlet.MyInvocation.MyCommand -UniqueId $eventId -Message "End" -AdditionalData @{Duration=$watch.Elapsed})
    }
    Process
    {
        if ($CurrentObject.ElementType -eq 'DeploymentTarget')
        {
            return $null
        }

        Write-Debug "$($PSCmdlet.MyInvocation.MyCommand) : CurentObject.DataContext = $($CurrentObject.DataContext)"

        if ($CurrentObject.DataContext)
        {
            $Path = $CurrentObject.DataContext
        }
        else
        {
            $Path = $CurrentObject.UniqueKey
        }
        
        Write-Debug "$($PSCmdlet.MyInvocation.MyCommand) : ElemntType=$($CurrentObject.ElementType), Path = $Path"

        if ($CurrentObject.Parent)
        {
            $ContainerPath = Get-BaseConfigurationDirectory -CurrentObject $CurrentObject.Parent
            if ($ContainerPath)
            {
                $Path = "$ContainerPath.$Path"
            }
        }

        Write-Output $Path

    }
}


function Initialize-ConfigurationDirectory
{
    [cmdletbinding(DefaultParameterSetName="none")]
    Param( 
        [Parameter(Mandatory=$true,ValueFromPipeline=$false)]
        [PSObject]$DeploymentTarget,

        [Parameter(Mandatory=$true,ValueFromPipeline=$false)]
        [PSObject]$ConfigurationRepositoryManager

    )
    Begin
    {
        $watch = [system.diagnostics.stopwatch]::StartNew()
        $eventId = Publish-ToMiddlewareLogs -Log (Get-LogMessage -Command $PSCmdlet.MyInvocation.MyCommand -Message "Start" -AdditionalData $PSBoundParameters)
    }
    End
    {
        $watch.Stop()
        $eventId = Publish-ToMiddlewareLogs -Log (Get-LogMessage -Command $PSCmdlet.MyInvocation.MyCommand -UniqueId $eventId -Message "End" -AdditionalData @{Duration=$watch.Elapsed})
    }
    Process
    {

        try
        {
            
            #First ensure RootConfigurationDirectory exist 
            Ensure-Directory -Path $ConfigurationRepositoryManager.LocalPath

            #Ensure BaseConfiguration Directory
            $BaseConfigurationDirectoryPath = $ConfigurationRepositoryManager.GetFullLocalPath($ConfigurationRepositoryManager.BaseConfigurationRootRelativePath)
            Ensure-Directory -Path $BaseConfigurationDirectoryPath

            #Ensure Environment Configuration Directory
            $EnvironmentConfigurationDirectoryPath = $ConfigurationRepositoryManager.GetFullLocalPath($DeploymentTarget.Environment)
            Ensure-Directory -Path ($EnvironmentConfigurationDirectoryPath)


            #Ensure directory structure
            $DeploymentTarget.Servers.Values | ForEach-Object {
                $server = $_
                $configurationFolders = $server.Folders | ? {$_.ConfigurationRepository -ne $null} 

                foreach($configurationFolder in $configurationFolders)
                {
                    $configurationFolderPath = Get-BaseConfigurationDirectory -CurrentObject $configurationFolder

                    #Ensure Base configuration Directory structure
                    $configurationFolderFullPath = Join-Path -Path $BaseConfigurationDirectoryPath -ChildPath $configurationFolderPath 
                    Ensure-Directory -Path $configurationFolderFullPath

                    #Ensure environment directory structure
                    $configurationFolderFullPath = Join-Path -Path $EnvironmentConfigurationDirectoryPath -ChildPath $configurationFolderPath 
                    Ensure-Directory -Path $configurationFolderFullPath

                }
            }

        }
        catch [Exception]
        {
            Publish-ToMiddlewareLogs -Log (Get-LogMessage -Command $PSCmdlet.MyInvocation.MyCommand -UniqueId $eventId -Category Error -Message "Error" -AdditionalData @{Exception=$_}) | Out-Null
        }
    }
}






